package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.Category;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.CategoryMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.CategoryService;
import com.atguigu.exam.service.QuestionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.json.GsonBuilderUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Autowired
    private QuestionMapper questionMapper;

    /*
    获取分类列表(包含题目数量)
    * */
    @Override
    public List<Category> getAllcategories() {
        //获取所有的分类信息,并按sort排序
        /*List<Category> categories = baseMapper.selectList(new LambdaQueryWrapper<Category>().orderByAsc(Category::getSort));
        System.out.println("categories = " + categories);*/
        List<Category> categories = baseMapper.selectList(new LambdaQueryWrapper<Category>().orderByAsc(Category::getSort));
        System.out.println("categories = " + categories);
        //获取所有分类的题目数量
        getQuestionCount(categories);
        return categories;
    }
    //获取每个分类下题目数量的方法
    private void getQuestionCount(List<Category> categories) {
        //获取所有题目的数量
        /*List<Map<Long,Long>> countlist=questionMapper.getCategoryCount();
        System.out.println("countlist = " + countlist);*/
        List<Map<Long, Long>> countlist = questionMapper.getCategoryCount();
        System.out.println("countlist = " + countlist);
        //将list转为map
        Map<Long, Long> collect = countlist.stream().collect(Collectors.toMap(
                m -> m.get("category_id"),
                m -> m.get("count")
        ));
        System.out.println("collect = " + collect);
        //遍历所有分类
        categories.forEach(category -> {
            //根据分类Id获取题目数量
            Long orDefault = collect.getOrDefault(category.getId(), 0L);
            //给分类设置题目数量
            category.setCount(orDefault);
                });
        System.out.println("======================");
    }

    /*
    获取分类树形结果
    * */

    @Override
    public List<Category> getCategoryTree() {
        //获取所有的分类列表，按照sort字段排序
        List<Category> categories = baseMapper.selectList(new LambdaQueryWrapper<Category>().orderByAsc(Category::getSort));
        System.out.println("categories = " + categories);
        //获取每个分类下的题目数量
        getQuestionCount(categories);
        //构建分类树结构
         List<Category> categorytree=bulidCategoryTree(categories);
        return categorytree;
    }

    /*
       添加分类
       * */
    @Override
    public void saveCategory(Category category) {
        //根据父类id和父类名称查询是否存在该对象
        //创建LambdaQueryWrapper对象
        LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //查询封装的条件
         categoryLambdaQueryWrapper.eq(Category::getParentId, category.getParentId()).eq(Category::getName, category.getName());
        //
        Category isExists = baseMapper.selectOne(categoryLambdaQueryWrapper);
        if (isExists!=null){
            //查询父类id
            Long parentId = category.getParentId();
            System.out.println("parentId = " + parentId);
            //根据id查询父类名称
            Category parentCategory = baseMapper.selectById(parentId);
            System.out.println("parentCategory = " + parentCategory);
            //已经存在该分类
        throw new ExamException(111,"父分类下"+parentCategory.getName()+"已经存在"+isExists.getName()+"分类,请重新输入");
        }
            baseMapper.insert(category);
        System.out.println("===============================");
    }
    /*
    更新分类
    注:ne为不等于
    * */
    @Override
    public void updateCategory(Category category) {
    //根据当前父类id查询所有子类列表
    List<Category> categories = baseMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getParentId, category.getParentId()));
    //查询子类列表下的所有名称
    List<String> Childrens = categories.stream().map(Category::getName).collect(Collectors.toList());
    if (Childrens.contains(category.getName())){
        //判断名称还是不是原来的名称
        Category oldCategory = baseMapper.selectOne(new LambdaQueryWrapper<Category>().eq(Category::getName, category.getName()));
        if (oldCategory.getId().equals(category.getId())){
            //证明是他自己 id正确可能在改其他内容
            baseMapper.updateById(category);
        }else {
            //证明不是它自己
            //获取父类id
            Long parentId = category.getParentId();
            //获取父类名称
            Category parentCategory = baseMapper.selectById(parentId);
            throw new ExamException(111,"父分类下"+parentCategory.getName()+"已经存在"+category.getName()+"分类,请重新输入");
        }
    }
    baseMapper.updateById(category);
    }
    /*
    删除分类
    * */
    @Override
    public void deleteCategory(Long id) {
     //判断该分类下是否有子分类或该分类下是否有题目
        Long l = baseMapper.selectCount(new LambdaQueryWrapper<Category>().eq(Category::getParentId, id));
        System.out.println("l = " + l);
        Long l1 = questionMapper.selectCount(new LambdaQueryWrapper<Question>().eq(Question::getCategoryId, id));
        System.out.println("l1 = " + l1);
        if (l>0 || l1>0){
            throw new ExamException(333,"该分类下有子分类或者该分类下有题目，不能删除");
        }
        baseMapper.deleteById(id);
    }


    //构建分类树结构的方法
    private List<Category> bulidCategoryTree(List<Category> categories) {
        //按照parent_id分组，获取每个父分类下的子分类列表
        Map<Long, List<Category>> collect = categories.stream().collect(Collectors.groupingBy(Category::getParentId));
        System.out.println("collect = " + collect);
        //遍历所有的分类
        categories.forEach(category -> {
            //获取当前分类的id
            Long id = category.getId();
            System.out.println("id = " + id);
            //根据当前分类的id从Map中获取子分类列表
            List<Category> childrenCategories = collect.getOrDefault(id, new ArrayList<>());
            System.out.println("childrenCategories = " + childrenCategories);
            //将子分类列表设置到分类对象中
            category.setChildren(childrenCategories);
            //获取所有子分类的题目数量之和
            long sum = childrenCategories.stream().mapToLong(c -> c.getCount() != null ? c.getCount() : 0L).sum();
            System.out.println("sum = " + sum);
            //获取当前类型的题目的数量
            Long count = category.getCount();
            System.out.println("count = " + count);
            //设置当前分类题目的数量是子分类题目的数量之和加上当前分类的题目数量
            category.setCount(count + sum);
        });
        //获取顶级分类列表，即parent_id为0的分类
        List<Category> categoryTree = categories.stream().filter(c -> c.getParentId() == 0L).collect(Collectors.toList());
        System.out.println("categoryTree = " + categoryTree);
        return categoryTree;
    }
}


